← All Articles

[Data Structure] Heap

Posted on

Heap

πŸ‘‰ λ³Έ ν¬μŠ€νŠΈλŠ” 자료ꡬ쑰의 κ°œλ…μ— μΆ”κ°€μ μœΌλ‘œ, 직접적인 C++ κ΅¬ν˜„μ„ ν†΅ν•œ λͺ…ν™•ν•œ 자료ꡬ쑰 이해λ₯Ό μœ„ν•΄ μž‘μ„±λ˜μ—ˆμŠ΅λ‹ˆλ‹€. πŸ‘ˆ

μš°μ„ μˆœμœ„ 큐λ₯Ό μ΄ν•΄ν•˜κΈ° μœ„ν•΄μ„  Heap 자료ꡬ쑰λ₯Ό λͺ…ν™•ν•˜κ²Œ μ΄ν•΄ν•˜μ—¬μ•Όλ§Œ ν•œλ‹€.

μš°λ¦¬λŠ” λ§Žμ€ μ•Œκ³ λ¦¬μ¦˜ λ¬Έμ œμ—μ„œ μš°μ„ μˆœμœ„ 큐λ₯Ό μ‚¬μš©ν•΄λ³Έ 적이 μžˆλ‹€. BFS μ•Œκ³ λ¦¬μ¦˜ 뿐 만 μ•„λ‹ˆλΌ λ‹€μ–‘ν•œ μš°μ„ μˆœμœ„, μŠ€μΌ€μ₯΄λ§ μ•Œκ³ λ¦¬μ¦˜μ—λ„ μš°μ„ μˆœμœ„ νλŠ” 빠지지 μ•Šκ³  μ‚¬μš©λœλ‹€.

μš°μ„ μˆœμœ„ 큐의 경우 λŠμŠ¨ν•œ μ •λ ¬ ν˜•νƒœμ˜ Heap 자료ꡬ쑰λ₯Ό 톡해 효과적으둜 νŠΉμ • 기쀀에 μ˜ν•œ 정렬값듀을 μ°¨λ‘€λ‘œ μΆ”μΆœν•΄λ‚Ό 수 μžˆλ‹€.



Complete Binary Tree

Heap은 μ™„μ „ 이진 트리 ν˜•νƒœλ₯Ό 가지고 μžˆλ‹€.

Complete Binary Tree(μ™„μ „ 이진 트리) : λ§ˆμ§€λ§‰ λ ˆλ²¨μ„ μ œμ™Έν•œ λͺ¨λ“  λ ˆλ²¨μ€ λͺ¨λ“  λ…Έλ“œκ°€ μ±„μ›Œμ Έ 있고, λ§ˆμ§€λ§‰ 레벨의 λ…Έλ“œλ“€μ€ μ™Όμͺ½λΆ€ν„° μ°¨λ‘€λ‘œ μ±„μ›Œμ Έ μžˆλŠ” 트리 ν˜•νƒœ

Full Binary Tree(포화 이진 트리) : μžμ‹ λ…Έλ“œλ₯Ό μ•„μ˜ˆ 가지지 μ•Šκ±°λ‚˜, 무쑰건 2개λ₯Ό κ°€μ§€λŠ” 이진 트리 ν˜•νƒœ


Min Heap : λΆ€λͺ¨ ν‚€ 값이 μžμ‹ λ…Έλ“œ ν‚€ 값보닀 μž‘μ€ μ™„μ „ 이진 트리, 루트 λ…Έλ“œκ°€ 트리 μƒμ—μ„œ κ°€μž₯ μž‘μ€ 값이닀.

Max Heap : λΆ€λͺ¨ ν‚€ 값이 μžμ‹ λ…Έλ“œ ν‚€ κ°’ 보닀 큰 μ™„μ „ 이진 트리, 루트 λ…Έλ“œκ°€ 트리 μƒμ—μ„œ κ°€μž₯ 큰 값이닀.


Heap μ‚½μž…, μ‚­μ œ μ—°μ‚°

μ‚½μž…

  1. μ™„μ „ 이진 트리의 λ‹€μŒμœΌλ‘œ λΉ„μ›Œμ Έ μžˆλŠ” λ…Έλ“œμ— 값을 μ‚½μž….
  2. μ‚½μž…ν•œ λ…Έλ“œμ˜ λΆ€λͺ¨ λ…Έλ“œμ™€ 값을 비ꡐ해 쑰건에 λ§žμ§€ μ•Šμ„ 경우 swap ν•΄μ€Œ
  3. 루트 λ…Έλ“œμ— λ„λ‹¬ν•˜κ±°λ‚˜, 더 이상 쑰건에 λ§žμ§€ μ•ŠλŠ” λ…Έλ“œκ°€ 없을 λ•Œ κΉŒμ§€ 1, 2번 κ³Όμ • 반볡

μ‚­μ œ -> μ‚­μ œμ— μ•žμ„œ Heap은 루트 λ…Έλ“œμ˜ μ›μ†Œλ§Œμ„ μ‚­μ œν•  수 있음(pop)

  1. 루트 λ…Έλ“œ μ›μ†Œ μ‚­μ œ
  2. λ§ˆμ§€λ§‰μ— μœ„μΉ˜ν•œ λ…Έλ“œλ₯Ό 루트 λ…Έλ“œ μœ„μΉ˜λ‘œ λŒμ–΄μ˜¬λ¦Ό
  3. μ΄λ™μ‹œν‚¨ 루트 λ…Έλ“œμ™€ μžμ‹λ…Έλ“œμ˜ 값을 비ꡐ해가며 쑰건에 λ§žμ§€ μ•Šμ„ 경우 swap ν•΄μ€Œ
  4. μ΅œν•˜λ‹¨ 레벨의 λ…Έλ“œκΉŒμ§€ λ„λ‹¬ν–ˆκ±°λ“  더 이상 쑰건에 λ§žμ§€ μ•ŠλŠ” λ…Έλ“œκ°€ 없을 λ•ŒκΉŒμ§€ swap κ³Όμ • 반볡


κ΅¬ν˜„ μ½”λ“œ

-> STL Library의 min heap μš°μ„ μˆœμœ„ 큐와 μœ μ‚¬ν•˜κ²Œ κ΅¬ν˜„ν•˜λ € μ‹œλ„ν•œ μ½”λ“œμ΄λ‹€.

#include <iostream>

#define SIZE 10000

using namespace std;

class MinHeap {
public :
    int *heap = new int[SIZE];
    int heapcount = 1;

    void swap(int *a, int *b) {
        int temp = *a;
        *a = *b;
        *b = temp;
    }

    int size() {
        return heapcount - 1;
    }

    bool isEmpty() {
        return heapcount == 1;
    }

    int top() {
        return heap[1];
    }

    void push(int num) {
        int curidx = heapcount;
        heap[heapcount++] = num;

        while (curidx > 1 && heap[curidx] < heap[curidx / 2]) {
            swap(&heap[curidx], &heap[curidx / 2]);
            curidx /= 2;
        }
    }

    void pop() {
        heap[1] = heap[--heapcount];

        int parent = 1, child = 2;
        if (child + 1 <= heapcount)
            child = (heap[child] > heap[child + 1]) ? child + 1 : child;

        while (child <= heapcount && heap[child] < heap[parent]) {
            swap(&heap[child], &heap[parent]);
            parent = child;
            child *= 2;
            if (child + 1 <= heapcount)
                child = (heap[child] > heap[child + 1]) ? child + 1 : child;
        }
    }
};


int main() {
    int tc, n, input;
    MinHeap minheap;

    cin >> tc;
    while (tc--) {
        cin >> n;
        while (n--) {
            cin >> input;
            minheap.push(input);
        }

        while (!minheap.isEmpty()) {
            cout << minheap.top() << ' ';
            minheap.pop();
        }
        cout << '\n';
    }

    return 0;
}



CSData Structure